package com.mspbots.sync.wise.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.sync.BaseGenericService;
import com.mspbots.sync.model.ExceptionLog;
import com.mspbots.sync.model.WiseUser;
import com.mspbots.sync.utils.WiseParamsUtils;
import com.mspbots.sync.utils.WiseResultBuildUtils;
import com.mspbots.sync.wise.client.ClientProperties;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * com.mspbots.sync.scheduled.service.UserService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/6/11
 */
@Log4j2
@Service
public class WiseUserService extends BaseGenericService {

    public Flux<JsonNode> getUsers(Map<String, String> queryParams) {
        Integer tenant = Integer.parseInt(queryParams.get("tenantId"));
        log.debug("This tenant {} get sync connect wise users.", +tenant);
        return this.onGetWiseProperties(tenant)
                .flatMapMany(configuration -> this.cwWebClient.fetch("/system/members", WiseParamsUtils.mapToMultiValueMapBuild(queryParams))
                        .subscriberContext(ctx -> ctx.put("properties", configuration)));

    }

    public Flux<WiseUser> getUsers(ClientProperties configuration) {
        log.debug("tenant {} , start sync connect wise time entry.", configuration.getTenantId());
        return this.cwWebClient.fetch("/system/members", WiseParamsUtils.paginationBuild("1", "inactiveFlag=false and licenseClass!='A'"))
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync getUsers error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-USER").msg("Connect wise sync users error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    return Flux.just(jsonNode);
                })
                .map(userNode -> WiseResultBuildUtils.buildWiseUser(configuration.getTenantId(), userNode))
                .flatMap(wiseUser -> this.getSkills(configuration, wiseUser.getCwUid())
                        .map(skills -> {
                            log.debug("User {} Skills {}", wiseUser.getCwUid(), skills);
                            wiseUser.setSkills(skills);
                            return wiseUser;
                        }).defaultIfEmpty(wiseUser))
                .flatMap(wiseUser -> this.getTeams(configuration,
                        this.objectMapper.convertValue(wiseUser.getExtend().get("serviceBoardTeamIds"), Integer[].class))
                        .map(jsonNode -> {
                            wiseUser.setTeamNames(jsonNode);
                            return wiseUser;
                        }).defaultIfEmpty(wiseUser))
                        /*.doOnNext(wiseUser -> this.loadRedisValue("sync-wise-users-" + wiseUser.getTenantId())
                        .subscribe(syncTime -> {
                            if (syncTime.isBefore(wiseUser.getUpdateTime())) {
                                this.recordRedisValue("sync-wise-users-" + wiseUser.getTenantId(),
                                        wiseUser.getUpdateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                            }
                        }))*/;

    }

    public Mono<JsonNode> getSkills(ClientProperties configuration, Long userId) {
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return cwWebClient.getRepository("system/members/" + userId + "/skills", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .defaultIfEmpty(this.objectMapper.createObjectNode());

    }

    public Mono<JsonNode> getTeams(ClientProperties configuration, Integer[] teamId) {
        if (ObjectUtils.isEmpty(teamId) || teamId.length == 0) {
            return Mono.empty();
        }
        MultiValueMap<String, String> params =
                WiseParamsUtils.paginationBuild("1",
                        "id in (" + StringUtils.arrayToCommaDelimitedString(teamId) + ")");
        log.debug("User get teams param {}", params);
        return cwWebClient.getRepository("/service/teams", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .defaultIfEmpty(this.objectMapper.createObjectNode());

    }

}
